/*
    This is a set of libraries to assist in OpenGl and Other Applications
    Copyright (C) 2008  The Modular Engine Team

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#define INTERFACEMODULE
#include <string>
#include "InterfaceObject.h"

namespace ModularEngine
{
	IMEvent::IMEvent()
	{
		mpFunc = 0;
		mpScript = 0;
		mpFunctor = 0;
		mType = -1;
	}

	void IMEvent::operator =(char *pScript)
	{
		if( mpScript )
			delete [] mpScript;
		mpScript = new char[strlen(pScript)+1];
		memset( mpScript, 0, sizeof( char )*strlen(pScript)+1 );
		strcpy( mpScript, pScript );
		mType = IME_SCRIPT;
	}

	template <class Func> void IMEvent::operator = (Func pFunc)
	{
		mType = IME_FUNCTION;

	}

	void IMEvent::operator = (IMFunctor *pFunctor)
	{
		mType = IME_FUNCTOR;
		mpFunctor = pFunctor;
	}

	void IMEvent::operator () ()
	{
		switch( mType )
		{
		case IME_FUNCTION:
			{
				if( mpFunc )
				{}
				// Research to be done here.
			} break;
		case IME_SCRIPT:
			{
				if( mpScript )
				{}
				// Need to have link to console module
			} break;
		case IME_FUNCTOR:
			{
				if( mpFunctor)
					(*mpFunctor)();
			} break;
		}
	}

	InterfaceObject::InterfaceObject()
	{
		mpParent = 0;
		mpValue = 0;
		mpName = 0;
	}

	InterfaceObject::~InterfaceObject()
	{
		Events.onDestroy();
		if( mpValue )
		{
			delete [] mpValue;
			mpValue = 0;
		}

		if( mpName )
		{
			delete [] mpName;
			mpName = 0;
		}
	}

	void InterfaceObject::Draw()
	{
		// Play draw event.
		Events.onDraw();
	}
	
	void InterfaceObject::Initialize()
	{
		Events.onInitialize();
	}

	bool InterfaceObject::FindChild( InterfaceObject *rObject )
	{
		// Recurses through all children/grandchilren etc. until rObject is found.
		// If rObject is not found, return false.
		for( deque<InterfaceObject *>::iterator i = mvChildren.begin(); i != mvChildren.end(); i++ )
		{
			if( *i == rObject || (*i)->FindChild( rObject ) )
				return true;
		}

		return false;
	}

	void InterfaceObject::AddChild( InterfaceObject *rObject )
	{
		if( this == rObject || FindChild( rObject ) )
		{
			// This will cause an infinite loop which would be bad.
			return;			
		} else {
			mvChildren.push_front( rObject );
		}
	}

	void InterfaceObject::SendMouseButton(ModularEngine::IMMouseInput rMouse)
	{
		if( rMouse.mState )
			// Mouse Events
			Events.onMouseDown();
		else 
			Events.onMouseUp();
	}

	void InterfaceObject::SendMouseMovement(IMMouseInput rMouse)
	{
		Events.onMouseMove();
	}

	void InterfaceObject::SendKeyInput( IMKeyInput rKey )
	{
		if( rKey.mState )
			Events.onKeyDown();
		else
			Events.onKeyUp();

	}
}